import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Properties;

public class Configuration {

	private static Configuration instance = null;
	private ArrayList<User> users = new ArrayList<>();
	private double MSG_DROP_RATE;
	private int MSG_MAX_DELAY;
	private int MSG_TIME_OUT;
	private String ORDERING;

	private Configuration() {
		Properties prop = new Properties();
		InputStream input = null;

		try {

			input = new FileInputStream("src/configFile");

			// load a properties file
			prop.load(input);
			
			String[] names = prop.getProperty("users").split(",");
			for (int i = 0; i < names.length; i++) {
				String name = names[i];
				String[] ad = prop.getProperty(name).split(":");
				users.add(new User(name, ad[0], Integer.parseInt(ad[1])));
			}
			
			MSG_DROP_RATE = Double.parseDouble(prop.getProperty("msg_drop_rate"));
			MSG_MAX_DELAY = Integer.parseInt(prop.getProperty("msg_max_delay"));
			MSG_TIME_OUT = Integer.parseInt(prop.getProperty("msg_time_out"));
			
			String ordering = prop.getProperty("ordering");
			this.ORDERING = ordering;
			if (ordering.equalsIgnoreCase("total")) {
				String[] ad = prop.getProperty("Sequencer").split(":");
				users.add(new User("Sequencer", ad[0], Integer.parseInt(ad[1])));
			}

		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

	public static Configuration getInstance() {
		if (instance == null) {
			instance = new Configuration();
		}
		return instance;
	}
	
	public ArrayList<User> getUsers() {
		return users;
	}
	
	public User getUserByName(String name) {
		for (User user : users) {
			if (user.getName().equalsIgnoreCase(name)) {
				return user;
			}
		}
		System.err.println("Warning: User " + name + " is null!");
		return null;
	}
	
	public double getMsgDropRate() {
		return MSG_DROP_RATE;
	}
	
	public int getMsgMaxDelay() {
		return MSG_MAX_DELAY;
	}
	
	public int getMsgTimeOut() {
		return MSG_TIME_OUT;
	}
	
	public String getOrdering() {
		return this.ORDERING;
	}
	
}